package warthog.scangen;

import java.util.*;


public final class StartState {

	final List<Rule> bolOnly = new ArrayList<Rule>();
	final List<Rule> anywhere = new ArrayList<Rule>();
	private String eofCode = null;
	static final TreeMap<String, StartState> states = new TreeMap<String, StartState>();
	public static StartState fetch(String name) {
		if (states.containsKey(name)) return states.get(name);
		else return new StartState(name);
	}
	static public void determinize() {
		for (StartState q:states.values()) q.determinizeOne();
	}
	private StartState(String name) {
		states.put(name, this);
	}

	public void addRule(Rule rule, boolean bol) {
		(bol?bolOnly:anywhere).add(rule);
	}
	
	DNode bolNode, startNode;
	private void determinizeOne() {
		Set<Node> foo = new HashSet<Node>();
		for (Rule r:anywhere) foo.add(r.start);
		startNode = DNode.fetch(foo);
		for (Rule r:bolOnly) foo.add(r.start);
		bolNode = DNode.fetch(foo);
	}

	public static void writeStarts(StringBuilder w) {
		//w.write("// StartState.writeStarts(...)\n");
		w.append("  static enum Start {\n   ");
		for (String name:states.keySet()) {
			StartState q=states.get(name);
			int a = q.startNode.color.index;
			int b = q.bolNode.color.index;
			w.append(" "+name+'('+a+','+b+"),");
		}
		w.append(";\n");
		w.append("    final int any, bol;\n");
		w.append("    Start(int any, int bol) { this.any=any; this.bol=bol; }\n");
		w.append("  }\n");
	}
	public static void writeEOFs(StringBuilder w) {
		for (String name:states.keySet()) {
			StartState q=states.get(name);
			w.append("    case "+name+": ");
			w.append(null==q.eofCode?"/* nothing */":q.eofCode);
			w.append(" break;\n");
		}
	}
	public void setEofCode(String eofCode) {
		this.eofCode = eofCode;
	}
}
